package com.weeho.dongyong.service;

import com.weeho.dongyong.constant.ConstantInterface;
import com.weeho.dongyong.dao.ApprovalDao;
import com.weeho.dongyong.entity.Approval;
import com.weeho.dongyong.entity.Organization;
import com.weeho.dongyong.entity.Task;
import com.weeho.dongyong.entity.TaskDetail;
import com.weeho.dongyong.utils.DateUtils;
import com.weeho.dongyong.utils.StringHelper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.weeho.dongyong.constant.ConstantInterface.APPROVAL_MAX;
import static com.weeho.dongyong.constant.ConstantInterface.APPROVAL_STATE_AGREE;
import static com.weeho.dongyong.constant.ConstantInterface.APPROVAL_STATE_UNREAD;

@Service
public class ApprovalService {
    @Autowired
    private ApprovalDao approvalDao;
    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private TaskDetailService taskDetailService;

    public int insertSelective(Approval record) {
        record.setCreateTime(DateUtils.parseToString(new Date()));
        return approvalDao.insertSelective(record);
    }

    public int updateByPrimaryKeySelective(Approval record) {
        record.setUpdateTime(DateUtils.parseToString(new Date()));
        return approvalDao.updateByPrimaryKeySelective(record);
    }

    public int deleteByPrimaryKey(String id) {
        return approvalDao.deleteByPrimaryKey(id);
    }

    public Approval selectByPrimaryKey(String id) {
        return approvalDao.selectByPrimaryKey(id);
    }

    public List<Approval> selectByCondition(Approval record) {
        return approvalDao.selectByCondition(record);
    }


    public int add(Task task) {
        Approval approval = new Approval();
        approval.setId(StringHelper.generatePrimaryKey());
        approval.setFkTaskId(task.getId());
        approval.setTaskName(task.getName());
        approval.setStartTime(task.getStartTime());
        approval.setEndTime(task.getEndTime());
        approval.setApplicantUser(task.getCreateUserId());
        approval.setState(APPROVAL_STATE_UNREAD);

        Organization organization = null;
        if (ConstantInterface.TASK_LEVEL_ONE.equals(task.getTaskLevel())) {
            organization = organizationService.getMaxLevel();
        } else {
            organization = organizationService.getFirstLevel();
        }

        approval.setApprovalQueue(organization.getOrganLevel());
        approval.setApprovalUserId(organization.getUserId());
        approval.setApprovalUserName(organization.getUserName());

        return insertSelective(approval);
    }

    public int nextApproval(Approval approval) {

        approval.setState(ConstantInterface.APPROVAL_STATE_SUCCESS);
        updateByPrimaryKeySelective(approval);


        approval = selectByPrimaryKey(approval.getId());
        Organization next = organizationService.getNextLevel(approval.getApprovalQueue());

        Approval appro = new Approval();
        appro.setId(StringHelper.generatePrimaryKey());
        appro.setFkTaskId(approval.getFkTaskId());
        appro.setTaskName(approval.getTaskName());


        appro.setApprovalUserId(next.getUserId());
        appro.setApprovalUserName(next.getUserName());
        appro.setApprovalQueue(next.getOrganLevel());


        appro.setStartTime(approval.getStartTime());
        appro.setEndTime(approval.getEndTime());
        appro.setApplicantUser(approval.getApplicantUser());
        appro.setFkHoldGoodsId(approval.getFkHoldGoodsId());
        return insertSelective(appro);
    }

    public boolean agree(Approval approval, String userId) {
        int flag = 0;

        approval.setState(APPROVAL_STATE_AGREE);
        flag = updateByPrimaryKeySelective(approval);
        switch (APPROVAL_MAX.compareTo(approval.getApprovalQueue())) {
            case 1:
                return nextApproval(approval) > 0;
            case 0:
                return sendInfor(approval, userId);
        }

        switch (approval.getApprovalQueue().intValue()) {
            case ConstantInterface.APPROVAL_QUEUE_USE:
                return userPrint(approval,userId);
            case ConstantInterface.APPROVAL_QUEUE_CHECK:
                return checkout(approval,userId);
            case ConstantInterface.APPROVAL_QUEUE_OUT:
                return outRegistered(approval,userId);
            case ConstantInterface.APPROVAL_QUEUE_BACK:
                return backRegistered(approval,userId);
        }

        return true;
    }


    public boolean sendInfor(Approval approval, String userId) {
        approval.setState(ConstantInterface.APPROVAL_STATE_SUCCESS);
        updateByPrimaryKeySelective(approval);

        Approval appro = copyToNext(approval, userId);
        appro.setState(ConstantInterface.APPROVAL_STATE_SUCCESS);
        appro.setApprovalQueue(new BigDecimal(ConstantInterface.APPROVAL_QUEUE_SEND));
        insertSelective(appro);


        Approval appro2 = copyToNext(approval, userId);
        appro2.setApprovalQueue(new BigDecimal(ConstantInterface.APPROVAL_QUEUE_USE));
        insertSelective(appro2);


        return true;
    }


    public boolean userPrint(Approval approval, String userId) {

        approval.setState(ConstantInterface.APPROVAL_STATE_SUCCESS);
        updateByPrimaryKeySelective(approval);


        Approval appro = copyToNext(approval, userId);
        appro.setApprovalQueue(new BigDecimal(ConstantInterface.APPROVAL_QUEUE_CHECK));

        insertSelective(appro);

        checkout(appro,userId);

        return true;
    }

    public boolean checkout(Approval approval, String userId) {
        approval.setState(ConstantInterface.APPROVAL_STATE_SUCCESS);
        updateByPrimaryKeySelective(approval);

        Approval appro = copyToNext(approval, userId);
        appro.setApprovalQueue(new BigDecimal(ConstantInterface.APPROVAL_QUEUE_OUT));
        insertSelective(appro);

        return true;
    }

    public boolean outRegistered(Approval approval,String userId) {
        approval.setState(ConstantInterface.APPROVAL_STATE_SUCCESS);
        updateByPrimaryKeySelective(approval);

        Approval appro = copyToNext(approval, userId);
        appro.setApprovalQueue(new BigDecimal(ConstantInterface.APPROVAL_QUEUE_BACK));
        insertSelective(appro);

        return true;
    }

    public boolean backRegistered(Approval approval,String userId) {
        approval.setState(ConstantInterface.APPROVAL_STATE_SUCCESS);
        updateByPrimaryKeySelective(approval);
        return true;
    }


    public Approval copyToNext(Approval approval,String userId) {

        approval = selectByPrimaryKey(approval.getId());
        Approval appro = new Approval();
        appro.setId(StringHelper.generatePrimaryKey());
        appro.setFkTaskId(approval.getFkTaskId());
        appro.setTaskName(approval.getTaskName());

        appro.setStartTime(approval.getStartTime());
        appro.setEndTime(approval.getEndTime());
        appro.setApplicantUser(approval.getApplicantUser());
        appro.setFkHoldGoodsId(approval.getFkHoldGoodsId());

        if(StringUtils.isNotEmpty(userId)){
            Organization user = organizationService.getOne(userId);
            appro.setApprovalUserId(user.getUserId());
            appro.setApprovalUserName(user.getUserName());
        }
        return appro;
    }

    public boolean reject(Approval approval) {
        int flag = 0;
        approval.setState(ConstantInterface.APPROVAL_STATE_REJECT);
        return 1 == updateByPrimaryKeySelective(approval);
    }

    public boolean end(Approval approval) {
        approval.setState(ConstantInterface.APPROVAL_STATE_END);
        return 1 == updateByPrimaryKeySelective(approval);
    }

    /**
     * get approval of one task
     *
     * @param taskId
     * @return
     */
    public List<Approval> getApprovalByTask(String taskId) {
        Approval approval = new Approval();
        approval.setFkTaskId(taskId);
        List<Approval> list = selectByCondition(approval);
        return list;
    }

    /**
     * 通过审批人获取审批流程
     *
     * @param userId
     * @return
     */
    public List<Approval> getApprovalByApprovalUser(String userId) {
        Approval approval = new Approval();
        approval.setApprovalUserId(userId);
        List<Approval> list = selectByCondition(approval);
        return list;
    }

    public List<Approval> getApprovalByApprovalUser(String userId, int state) {
        Approval approval = new Approval();
        approval.setApprovalUserId(userId);
        List<Approval> list = selectByCondition(approval);
        return list;
    }


    public List<Approval> getFinishTask(String userId){
        Approval approval = new Approval();
        approval.setApplicantUser(userId);
        approval.setApprovalQueue(APPROVAL_MAX);
        approval.setState(APPROVAL_STATE_AGREE);

        return selectByCondition(approval);
    }

    public List<Approval> getUnFinishTask(String userId){
        Approval approval = new Approval();
        approval.setApplicantUser(userId);
        approval.setState(APPROVAL_STATE_UNREAD);
        List<Approval> firstList = selectByCondition(approval);
        List<Approval> list = new ArrayList<>();
        for(Approval a : firstList){
            if(APPROVAL_MAX.compareTo(a.getApprovalQueue()) >= 0 ){
                list.add(a);
            }
        }

        return list;
    }

    /**
     * 获取任务审批状态
     * @param taskId
     * @return 1:some 2:待审批
     */
    public int getTaskApprovalState(String taskId){

        List<TaskDetail> taskDetailList = taskDetailService.getTaskDetailByTaskId(taskId);
        for(TaskDetail t : taskDetailList){
            Approval a  = new Approval();
            a.setApprovalQueue(new BigDecimal(1));
            a.setFkHoldGoodsId(t.getFkGoodsId());

            List<Approval> approvals = selectByCondition(a);
            for(Approval ap : approvals){
                if(ap.getState() != APPROVAL_STATE_UNREAD) return 1;
            }
        }
        return 2;
    }
}